package com.opengroupe.util;

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import com.opengroupe.entities.Question;
import com.opengroupe.entities.Reponse;

/**
 * QRH Utilities class
 * 
 * @author MMB11447
 *
 */
public final class QrhUtil {
	
	/**
	 * Updates the specified map with the given values.
	 * 
	 * @param questionReponses {@link Map} to be updated
	 * @param question {@link Question} map's key
	 * @param reponse {@link Reponse} to be added
	 */
	public static void updateMap(Map<Question, Set<Reponse>> questionReponses, 
			Question question, Reponse reponse) {
		if(questionReponses.containsKey(question)) {
			Set<Reponse> reponses = questionReponses.get(question);
			reponses.add(reponse);
		} else {
			Set<Reponse> reps = new TreeSet<Reponse>(new QrhUtil().new ReponseComparator());
			reps.add(reponse);
			questionReponses.put(question, reps);
		}
	}

	/**
	 * Corrects the "questionnaire" by comparing candidate's response with 
	 * the correct ones linked to the {@link Question}
	 * 
	 * @param questionReponses each {@link Question} is attached to set of {@link Reponse}
	 * @return each {@link Question} is associated to <code>true</code> if {@link Reponse} 
	 * is the good one. <code>false</code> otherwise
	 */
	public static Map<Question, Boolean> corrigerQuestionnaire(Map<Question, Set<Reponse>> questionReponses) {
		Map<Question, Boolean> resultat = new HashMap<Question, Boolean>();
		for(Map.Entry<Question, Set<Reponse>> entry: questionReponses.entrySet()) {
			Question question = entry.getKey();
			Set<Reponse> reponses = entry.getValue();
			boolean correct = isEqual(question.getReponsesCorrectes(), reponses);
			resultat.put(question, new Boolean(correct));
		}
		
		return resultat;
	}

	/**
	 * Returns <code>true</code> if the two sets contains the same 
	 * {@link Reponse}. <code>false</code> otherwise.
	 * 
	 * @param reponsesCorrectes initial values
	 * @param reponses to be compared
	 * @return <code>true</code> or <code>false</code>
	 */
	private static boolean isEqual(Set<Reponse> reponsesCorrectes,
			Set<Reponse> reponses) {
		if(reponsesCorrectes.size() != reponses.size()) {
			return false;
		}

		return reponsesCorrectes.containsAll(reponses)
				&& reponses.containsAll(reponsesCorrectes);
	}
	
	/**
	 * Class which compares {@link Reponse} 
	 * @author MMB11447
	 *
	 */
	private class ReponseComparator implements Comparator<Reponse> {

		public int compare(Reponse o1, Reponse o2) {
			return o1.getContenuReponse().compareTo(o2.getContenuReponse());
		}
		
	}

}
